package com.example.shiro.common.config.shiro;



import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
//import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.servlet.Filter;

/**
 * @auther 严旭平
 * @date 2020/4/1616:27
 * @Description
 * HashedCredentialsMatcher是用来处理MD5加密的
 * MyShiroRealm是你待会儿要自定义的realm，在这里面处理授权以及认证
 * SecurityManager核心部件
 * ShiroFilterFactoryBean过滤规则的处理中心
 * DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor一起使用可以开启授权注解
 * SimpleMappingExceptionResolver异常处理器
 *
 * 参考地址：https://blog.csdn.net/njpkhuan/article/details/100563123
 */
@Configuration
public class ShiroConfig {

    /**
     * 注入realm对象
     * @return
     */
    @Bean("myShiroRealm")
    public MyShiroRealm MyShiroRealm(){
        return new MyShiroRealm();
    }


    /**
     * 配置核心安全事务管理器
     *
     * @return org.apache.shiro.mgt.SecurityManager
     * @author zhuyongsheng
     * @date 2019/8/15
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置自定义realm.
        securityManager.setRealm( this.MyShiroRealm() );
//        //配置记住我
//        securityManager.setRememberMeManager(cookieRememberMeManager());
//        //配置缓存管理器
//        securityManager.setCacheManager(ehCacheManager());
//        //配置session管理器
//        securityManager.setSessionManager(shiroSessionManager());
        return securityManager;
    }



    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意：初始化ShiroFilterFactoryBean的时候需要注入：SecurityManager
     * Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截
     * @param securityManager
     * @return
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean factory( DefaultWebSecurityManager securityManager ) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        /**
         * 添加自定义过滤器
         */
        Map<String, Filter> filterMap = new HashMap<>(16 );
        filterMap.put( "jwt", new JWTFilter() );
        factoryBean.setFilters( filterMap );

        /**
         * 必须设置 SecurityManager,Shiro的核心安全接口
         */
        factoryBean.setSecurityManager(securityManager);

        /*
         * 自定义url规则，配置接口访问权限
         */
        Map<String, String> filterRuleMap = new HashMap<>(16);

        /**
         * 放弃拦截swagger地址
         */
        filterRuleMap.put("/swagger-ui.html", "anon");
        filterRuleMap.put("/swagger-resources", "anon");
        filterRuleMap.put("/v2/api-docs", "anon");
        filterRuleMap.put("/webjars/springfox-swagger-ui/**", "anon");
        filterRuleMap.put("/configuration/security", "anon");
        filterRuleMap.put("/configuration/ui", "anon");

        /**
         * 放弃拦截登录接口
         */
        filterRuleMap.put( "/login", "anon" );
        /**
         * 放弃拦截静态文件
         */
        filterRuleMap.put( "/login", "anon" );

        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/**", "jwt");

        factoryBean.setFilterChainDefinitionMap( filterRuleMap );
        return factoryBean;
    }


    /**
     * 需要权限认证的时候放开下面两个方法的注释即可
     */
//    /**
//     *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions)
//     * @return
//     */
//    @Bean
//    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
//        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
//        advisorAutoProxyCreator.setProxyTargetClass(true);
//        return advisorAutoProxyCreator;
//    }
//
//    /**
//     * 开启aop注解支持
//     * @param securityManager
//     * @return
//     */
//    @Bean
//    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
//        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
//        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
//        return authorizationAttributeSourceAdvisor;
//    }


}
